﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web;
using DataBuddy;
using Astro.Core;

namespace Astro.Web.astro_admin
{
    /// <summary>
    /// Summary description for Ajax
    /// </summary>
    public class Ajax : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.RequestType == "POST" && context.Request.IsAuthenticated)
            {
                IAstroUser user = AstroUsers.Current;
                if (user == null)
                    return;

                if (!RolePermissionManager.CanViewControlPanel(user))
                    return;

                context.Response.ContentType = "text/plain";


                switch (context.Request.QueryString["command"])
                {
                    case "deleteComment":

                        Comment c = new Comment(context.Request.Form["commentid"]);

                        if (RolePermissionManager.GetPermissions(c.Post.CategoryId, AstroUsers.Current).Publish)
                        {
                            Comment.Delete(context.Request.Form["commentid"]);
                            context.Response.Write("success");
                        }

                        break;

                    case "deleteCommentWithStatus":

                        Comment c1 = new Comment(context.Request.Form["commentid"]);

                        if (RolePermissionManager.GetPermissions(c1.Post.CategoryId, AstroUsers.Current).Publish)
                        {
                            Comment.Delete(context.Request.Form["commentid"]);
                            context.Response.Write("The comment was deleted. <a href=\"javascript:void(0);\" onclick=\"Comments.unDelete('" + new Urls().AdminAjax + "'," + context.Request.Form["commentid"] + "); return false;\">Undo?</a>");
                        }
                        break;

                    case "unDelete":
                        Comment c2 = new Comment(context.Request.Form["commentid"]);

                        if (RolePermissionManager.GetPermissions(c2.Post.CategoryId, AstroUsers.Current).Publish)
                        {
                            Comment comment = new Comment(context.Request.Form["commentid"]);
                            comment.IsDeleted = false;
                            comment.Save();
                            context.Response.Write("The comment was un-deleted. You may need to refresh the page to see it");
                        }
                        break;

                    case "approve":
                        Comment c3 = new Comment(context.Request.Form["commentid"]);

                        if (RolePermissionManager.GetPermissions(c3.Post.CategoryId, AstroUsers.Current).Publish)
                        {
                            Comment cmt = new Comment(context.Request.Form["commentid"]);
                            cmt.IsDeleted = false;
                            cmt.IsPublished = true;
                            cmt.Save();
                            context.Response.Write("The comment was un-deleted and/or approved. You may need to refresh the page to see it");
                        }
                        break;

                    case "deletePost":
                        try
                        {
                            Post postToDelete = new Post(context.Request.Form["postid"]);

                            Permission perm = RolePermissionManager.GetPermissions(postToDelete.CategoryId, user);

                            if (AstroUsers.IsAdmin(user) || perm.Publish)
                            {
                                postToDelete.IsDeleted = true;
                                postToDelete.Save(user.Name, DateTime.Now);

                                //Post.Delete(context.Request.Form["postid"]);
                                //ZCache.RemoveByPattern("Posts-");
                                //ZCache.RemoveCache("Post-" + context.Request.Form["postid"]);
                                context.Response.Write("The post was deleted. <a href=\"javascript:void(0);\" onclick=\"Posts.unDeletePost('" + new Urls().AdminAjax + "'," + context.Request.Form["postid"] + "); return false;\">Undo?</a>");
                            }
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "unDeletePost":
                        Post p = new Post(context.Request.Form["postid"]);
                        p.IsDeleted = false;
                        p.Save();
                        //ZCache.RemoveByPattern("Posts-");
                        //ZCache.RemoveCache("Post-" + context.Request.Form["postid"]);                
                        //context.Response.Write("The post was un-deleted. You may need to fresh the page to see it");
                        break;

                    case "permanentDeletePost":
                        Post tempPost = new Post(context.Request.Form["postid"]);
                        Post.DestroyDeletedPost(tempPost.Id);
                        context.Response.Write(tempPost.Title);
                        break;

                    case "createdWidget":
                        string widgetID = context.Request.Form["id"];
                        List<WidgetDescription> the_widgets = Widgets.GetAvailableWidgets();
                        Widget widget = null;
                        foreach (WidgetDescription wia in the_widgets)
                        {
                            if (wia.UniqueId == widgetID)
                            {
                                widget = Widgets.Create(wia.WidgetType);
                                break;
                            }
                        }

                        context.Response.Write(widget.Id.ToString());

                        break;

                    case "updateWidgetsOrder":

                        try
                        {
                            string listID = context.Request.Form["id"];
                            string list = "&" + context.Request.Form["list"];

                            Widgets.ReOrder(listID, list);

                            //StreamWriter sw = new StreamWriter(context.Server.MapPath("~/widgets.txt"), true);
                            //sw.WriteLine(DateTime.Now);
                            //sw.WriteLine();
                            //sw.WriteLine(context.Request.Form["left"]);
                            //sw.WriteLine(context.Request.Form["right"]);
                            //sw.WriteLine(context.Request.Form["queue"]);
                            //sw.WriteLine();
                            //sw.Close();

                            context.Response.Write("Saved!");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "deleteWidget":

                        string deleteID = context.Request.Form["id"];
                        Widgets.Delete(deleteID);
                        context.Response.Write("The widget was removed!");

                        break;

                    case "createTextLink":
                        DynamicNavigationItem di = new DynamicNavigationItem();
                        di.NavigationType = DynamicNavigationType.Link;
                        di.Text = context.Request.Form["text"];
                        di.Href = context.Request.Form["href"];
                        di.Id = Guid.NewGuid();
                        NavigationSettings.Add(di);
                        context.Response.Write(di.Id);

                        break;

                    case "deleteTextLink":
                        Guid g = new Guid(context.Request.Form["id"]);
                        NavigationSettings.Remove(g);
                        context.Response.Write("Success");
                        break;

                    case "reOrderNavigation":
                        try
                        {
                            string navItems = "&" + context.Request.Form["navItems"];
                            NavigationSettings.ReOrder(navItems);
                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "addNavigationItem":


                        try
                        {
                            if (context.Request.Form["type"] == "Post")
                            {
                                Post navPost = Post.FetchByColumn(Post.Columns.UniqueId, new Guid(context.Request.Form["id"]));
                                DynamicNavigationItem item = new DynamicNavigationItem();
                                item.PostId = navPost.Id;
                                item.Id = navPost.UniqueId;
                                item.NavigationType = DynamicNavigationType.Post;
                                NavigationSettings.Add(item);
                                context.Response.Write("Success");
                            }
                            else if (context.Request.Form["type"] == "Category")
                            {
                                Category navCategory = Category.FetchByColumn(Category.Columns.UniqueId, new Guid(context.Request.Form["id"]));
                                DynamicNavigationItem item = new DynamicNavigationItem();
                                item.CategoryId = navCategory.Id;
                                item.Id = navCategory.UniqueId;
                                item.NavigationType = DynamicNavigationType.Category;
                                NavigationSettings.Add(item);
                                context.Response.Write("Success");
                            }

                        }
                        catch (Exception exp)
                        {
                            context.Response.Write(exp.Message);
                        }

                        break;

                    case "reOrderPosts":
                        try
                        {
                            Dictionary<int, Post> posts = new Dictionary<int, Post>();
                            DataBuddy.Query query = Post.CreateQuery();
                            query.AndWhere(Post.Columns.CategoryId, int.Parse(context.Request.QueryString["id"]));
                            foreach (Post post in PostCollection.FetchByQuery(query))
                            {
                                posts[post.Id] = post;
                            }

                            string postOrder = context.Request.Form["posts"];
                            int orderNumber = 1;
                            foreach (string sId in postOrder.Split('&'))
                            {
                                Post post = null;
                                posts.TryGetValue(int.Parse(sId), out post);
                                if (post != null && post.SortOrder != orderNumber)
                                {
                                    post.SortOrder = orderNumber;
                                    post.Save();
                                }

                                orderNumber++;
                            }

                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "reOrderHomePosts":
                        try
                        {
                            Dictionary<int, Post> posts = new Dictionary<int, Post>();
                            DataBuddy.Query query = Post.CreateQuery();
                            query.AndWhere(Post.Columns.IsHome, true);
                            foreach (Post post in PostCollection.FetchByQuery(query))
                            {
                                posts[post.Id] = post;
                            }

                            string postOrder = context.Request.Form["posts"];
                            int orderNumber = 1;
                            foreach (string sId in postOrder.Split('&'))
                            {
                                Post post = null;
                                posts.TryGetValue(int.Parse(sId), out post);
                                if (post != null && post.HomeSortOrder != orderNumber)
                                {
                                    post.HomeSortOrder = orderNumber;
                                    post.Save();
                                }

                                orderNumber++;
                            }

                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "categoryForm":

                        int selectedCategory = int.Parse(context.Request.QueryString["category"] ?? "-1");
                        int postId = int.Parse(context.Request.QueryString["post"] ?? "-1");
                        NameValueCollection nvcCustomFields;
                        if (postId > 0)
                            nvcCustomFields = new Post(postId).CustomFields();
                        else
                            nvcCustomFields = new NameValueCollection();

                        CustomPostFormSettings cfs = CustomPostFormSettings.Get(selectedCategory);

                        if (cfs.HasFields)
                        {
                            foreach (CustomField cf in cfs.Fields)
                            {
                                if (context.Request.Form[cf.Id.ToString()] != null)
                                    nvcCustomFields[cf.Name] = context.Request.Form[cf.Id.ToString()];
                            }

                            context.Response.Write(cfs.GetHtmlForm(nvcCustomFields, (postId < 1)));
                        }
                        else
                            context.Response.Write("");

                        break;

                    case "toggleEventStatus":

                        try
                        {
                            EventDetails ed = Events.GetEvent(context.Request.QueryString["t"]);
                            ed.Enabled = !ed.Enabled;

                            if (ed.Enabled)
                                ed.Event.EventEnabled();
                            else
                                ed.Event.EventDisabled();

                            Events.Save(ed);

                            context.Response.Write(ed.Enabled ? "Enabled" : "Disabled");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "buildMainFeed":
                        try
                        {
                            FileInfo mainFeedFileInfo = new FileInfo(HttpContext.Current.Server.MapPath("~/Feed/Default.aspx"));

                            if (!mainFeedFileInfo.Directory.Exists)
                                mainFeedFileInfo.Directory.Create();

                            using (StreamWriter sw = new StreamWriter(mainFeedFileInfo.FullName, false))
                            {
                                sw.WriteLine("<%@ Page Language=\"C#\" Inherits=\"Astro.Core.RSS\" %>");
                                sw.Close();
                            }

                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                            return;
                        }

                        break;

                    case "removeFeedData":
                        try
                        {
                            FeedManager.RemoveFeedData();
                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;

                    case "buildCategoryPages":

                        try
                        {
                            CategoryCollection cc = new CategoryController().GetCachedCategories();
                            foreach (Category cat in cc)
                                cat.WritePages();


                            context.Response.Write("Success");
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                            return;
                        }

                        break;

                    case "buildPages":

                        try
                        {

                            Query q = Post.CreateQuery();
                            q.PageIndex = Int32.Parse(context.Request.Form["p"]);
                            q.PageSize = 20;
                            q.OrderByDesc(Post.Columns.Id);

                            PostCollection pc = PostCollection.FetchByQuery(q);
                            if (pc.Count > 0)
                            {

                                foreach (Post postToWrite in pc)
                                {
                                    postToWrite.WritePages();
                                    foreach (string tagName in Util.ConvertStringToList(postToWrite.TagList))
                                    {
                                        if (!string.IsNullOrEmpty(tagName))
                                            Tag.WritePage(tagName);
                                    }

                                }

                                context.Response.Write("Next");
                            }
                            else
                            {
                                context.Response.Write("Success");
                            }

                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                            return;
                        }



                        break;

                    case "importPosts":

                        try
                        {
                            Post newPost = new Post();
                            newPost.Title = HttpContext.Current.Server.HtmlDecode(context.Request.Form["subject"].ToString());

                            string postName = HttpContext.Current.Server.HtmlDecode(context.Request.Form["name"].ToString());

                            PostCollection pc = new PostCollection();

                            if (!String.IsNullOrEmpty(postName))
                            {
                                Query q = Post.CreateQuery();
                                q.AndWhere(Post.Columns.Name, Util.CleanForUrl(postName));
                                pc.LoadAndCloseReader(q.ExecuteReader());
                            }

                            if (pc.Count > 0)
                            {
                                newPost.Name = "[RENAME ME - " + Guid.NewGuid().ToString().Substring(0, 7) + "]";
                                newPost.Status = (int)PostStatus.Draft;
                            }
                            else if (String.IsNullOrEmpty(postName))
                            {
                                newPost.Name = "[RENAME ME - " + Guid.NewGuid().ToString().Substring(0, 7) + "]";
                                newPost.Status = (int)PostStatus.Draft;
                            }
                            else
                            {
                                newPost.Name = postName;
                                newPost.Status = (int)PostStatus.Publish;
                            }

                            if (String.IsNullOrEmpty(newPost.Title))
                                newPost.Title = newPost.Name;



                            newPost.PostBody = HttpContext.Current.Server.HtmlDecode(context.Request.Form["body"].ToString());
                            newPost.CreatedOn = Convert.ToDateTime(context.Request.Form["createdon"]);
                            newPost.CreatedBy = context.Request.Form["author"];
                            newPost.ModifiedBy = context.Request.Form["author"];
                            newPost.TagList = context.Request.Form["tags"];
                            newPost.ContentType = "text/html";
                            newPost.CategoryId = Convert.ToInt32(context.Request.Form["category"]);
                            newPost.UserName = context.Request.Form["author"];
                            newPost.EnableComments = true;
                            newPost.Published = Convert.ToDateTime(context.Request.Form["createdon"]);
                            newPost.IsPublished = Convert.ToBoolean(context.Request.Form["published"]);

                            // this was causing too many posts to be in draft status.
                            // updated text on migrator to flag users to just move their content/binary directory
                            // into astro's root
                            //if (context.Request.Form["method"] == "dasBlog")
                            //{
                            //    if (newPost.Body.ToLower().Contains("/content/binary/"))
                            //        newPost.Status = (int)PostStatus.Draft;
                            //}

                            newPost.Save(AstroUsers.Current.Name);

                            int postid = Convert.ToInt32(context.Request.Form["postid"]);

                            IMigrateFrom temp = null;

                            switch (context.Request.Form["method"])
                            {
                                case "CS2007Database":

                                    CS2007Database db = new CS2007Database();
                                    temp = (IMigrateFrom)db;

                                    break;
                                case "Wordpress":

                                    Wordpress wp = new Wordpress();
                                    temp = (IMigrateFrom)wp;

                                    break;

                                case "BlogML":

                                    BlogML bml = new BlogML();
                                    temp = (IMigrateFrom)bml;

                                    break;

                                case "CS21Database":
                                    CS21Database csDb = new CS21Database();
                                    temp = (IMigrateFrom)csDb;

                                    break;

                                case "dasBlog":
                                    dasBlog dasb = new dasBlog();
                                    temp = (IMigrateFrom)dasb;

                                    break;
                            }

                            List<MigratorComment> comments = temp.GetComments(postid);

                            foreach (MigratorComment cmnt in comments)
                            {
                                Comment ct = new Comment();
                                ct.PostId = newPost.Id;
                                ct.Body = cmnt.Body;
                                ct.Published = cmnt.PublishedOn;
                                ct.IPAddress = cmnt.IPAddress;
                                ct.WebSite = cmnt.WebSite;
                                ct.Email = string.IsNullOrEmpty(cmnt.Email) ? "" : cmnt.Email;
                                ct.Name = string.IsNullOrEmpty(cmnt.UserName) ? "" : cmnt.UserName;
                                ct.IsPublished = cmnt.IsPublished;
                                ct.IsTrackback = cmnt.IsTrackback;
                                ct.SpamScore = cmnt.SpamScore;
                                ct.DontSendEmail = true;
                                ct.DontChangeUser = true;

                                ct.Save();

                                Comment ctemp = new Comment(ct.Id);
                                ctemp.DontSendEmail = true;
                                ctemp.DontChangeUser = true;
                                ctemp.Body = HttpContext.Current.Server.HtmlDecode(ctemp.Body);
                                ctemp.Save();
                            }

                            if (newPost.Status == (int)PostStatus.Publish)
                                context.Response.Write("Success" + context.Request.Form["panel"]);
                            else
                                context.Response.Write("Warning" + context.Request.Form["panel"]);
                        }
                        catch (Exception ex)
                        {

                            context.Response.Write(context.Request.Form["panel"] + ":" + ex.Message);
                        }

                        break;

                    case "saveHomeSortStatus":

                        SiteSettings siteSettings = SiteSettings.Get();
                        siteSettings.UseCustomHomeList = bool.Parse(context.Request.Form["ic"]);
                        siteSettings.Save();
                        context.Response.Write("Success");

                        break;

                    case "checkCategoryPermission":

                        try
                        {
                            int catID = Int32.Parse(context.Request.QueryString["category"]);
                            string permissionName = context.Request.QueryString["permission"];
                            Permission perm = RolePermissionManager.GetPermissions(catID, user);

                            bool permissionResult = false;
                            switch (permissionName)
                            {
                                case "Publish":
                                    permissionResult = perm.Publish;
                                    break;
                                case "Read":
                                    permissionResult = perm.Read;
                                    break;
                                case "Edit":
                                    permissionResult = perm.Edit;
                                    break;
                            }

                            context.Response.Write(permissionResult.ToString().ToLower());
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write(ex.Message);
                        }
                        break;
                }
            }
            else
            {
                context.Response.ContentType = "text/plain";
                IAstroUser user = AstroUsers.Current;
                if (user == null)
                    return;

                switch (context.Request.QueryString["command"])
                {
                    case "generatorPostName":
                        string postTitle = context.Request.QueryString["title"];
                        string postName = Util.CleanForUrl(context.Server.HtmlDecode(postTitle));
                        postName = Util.UnCleanForUrl(postName);

                        context.Response.Write(postName);

                        break;

                    case "categorySort":
                        string _ids = context.Request.QueryString["ids"];
                        string[] ids = _ids.Split(',');

                        for (int i = 0; i < ids.Length; i++)
                        {
                            Category sortc = new Category(ids[i]);
                            if (sortc != null)
                            {
                                sortc.SortOrdering = i;
                                sortc.Save();
                            }
                        }

                        CategoryController.Reset();
                        context.Response.Write("Sort up");

                        break;

                    case "customFieldSort":
                        string _sortCategoryId = context.Request.QueryString["categoryId"] ?? "-1";
                        CustomPostFormSettings cfs = CustomPostFormSettings.Get(Convert.ToInt32(_sortCategoryId), false);
                        CustomPostFormSettings ncfs = new CustomPostFormSettings();

                        ncfs.CategoryId = cfs.CategoryId;
                        ncfs.FormCategoryId = cfs.FormCategoryId;
                        ncfs.Name = cfs.Name;
                        ncfs.Fields = new List<CustomField>();

                        string _sids = context.Request.QueryString["ids"];
                        string[] sids = _sids.Split(',');

                        for (int i = 0; i < sids.Length; i++)
                        {
                            ncfs.Fields.Add(cfs.Fields.Find(delegate(CustomField cf) { return cf.Id.Equals(new Guid(sids[i])); }));
                        }

                        ncfs.Save();
                        break;

                    case "categoryCustomFieldSort":
                        string _customSortCategoryId = context.Request.QueryString["categoryId"] ?? "-1";
                        CustomCategoryFormSettings ccfs = CustomCategoryFormSettings.Get(Convert.ToInt32(_customSortCategoryId), false);
                        CustomCategoryFormSettings nccfs = new CustomCategoryFormSettings();

                        nccfs.CategoryId = ccfs.CategoryId;
                        nccfs.Name = ccfs.Name;
                        nccfs.Fields = new List<CustomField>();

                        string _scids = context.Request.QueryString["ids"];
                        string[] scids = _scids.Split(',');

                        for (int i = 0; i < scids.Length; i++)
                        {
                            nccfs.Fields.Add(ccfs.Fields.Find(delegate(CustomField cf) { return cf.Id.Equals(new Guid(scids[i])); }));
                        }

                        nccfs.Save();
                        break;

                    case "userCustomFieldSort":
                        CustomUserFormSettings ucfs = CustomUserFormSettings.Get();
                        CustomUserFormSettings nucfs = new CustomUserFormSettings();

                        nucfs.Name = ucfs.Name;
                        nucfs.Fields = new List<CustomField>();

                        string _snids = context.Request.QueryString["ids"];
                        string[] snids = _snids.Split(',');

                        for (int i = 0; i < snids.Length; i++)
                        {
                            nucfs.Fields.Add(ucfs.Fields.Find(delegate(CustomField cf) { return cf.Id.Equals(new Guid(snids[i])); }));
                        }

                        nucfs.Save();
                        break;

                    case "commentCustomFieldSort":
                        CustomCommentFormSettings cccfs = CustomCommentFormSettings.Get(context.Request.QueryString["typeid"]);
                        CustomCommentFormSettings nccucfs = new CustomCommentFormSettings();

                        nccucfs.CommentTypeId = cccfs.CommentTypeId;
                        nccucfs.Name = cccfs.Name;
                        nccucfs.Fields = new List<CustomField>();

                        string _sccnids = context.Request.QueryString["ids"];
                        string[] sccnids = _sccnids.Split(',');

                        for (int i = 0; i < sccnids.Length; i++)
                        {
                            nccucfs.Fields.Add(cccfs.Fields.Find(delegate(CustomField cf) { return cf.Id.Equals(new Guid(sccnids[i])); }));
                        }

                        nccucfs.Save();
                        break;
                }
            }

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    // end namespace
}